import traceback
from typing import Any, Dict

import requests

from utils.CarUtil import CarUtil
from utils.LogUtil import LogUtil


class CarHttp:
  """ http 请求类

  Returns:
      class CarHttp(object): 返回一个 CarHttp 类
  """

  #region properties

  __httpConfig: Dict
  __defaultHttpConfig: Dict = {
      'host': 'https://www.dongchedi.com',
      "headers":
          {
              "User-Agent":
                  "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36 Edg/97.0.1072.62",
              "Content-Type":
                  "application/json; charset=UTF-8",
          },
  }

  @property
  def httpConfig(self) -> Dict:
    return self.__httpConfig if self.__httpConfig else self.__defaultHttpConfig

  #endregion

  def __init__(self, httpConfig: Dict = None):
    if httpConfig and len(httpConfig.get("headers", dict())) < 1:
      httpConfig['headers'] = self.__defaultHttpConfig['headers']
    self.__httpConfig = httpConfig

  # 发起请求
  # @timmer
  def req(
      self,
      method: str,
      path: str,
      headers: Any = None,
      data: Any = None
  ) -> requests.Response:
    """发起请求

    Args:
        method (str): get、post、delete、put 等 requests 包支持方法
        path (str): 请求路径，不包含主机域名
        headers (Any, optional): 请求头部. Defaults to None.
        data (Any, optional): 请求数据. Defaults to None.

    Returns:
        res (class:`Response <Response>` object): 响应对象
    """

    res: requests.Response = None
    url = None
    try:
      _url = self.combineUrl(path)
      _headers = CarUtil.dictMerge(
          self.httpConfig.get("headers",
                              dict()),
          headers,
      )
      res = requests.request(
          url=_url,
          method=method,
          data=data,
          headers=_headers,
          timeout=self.httpConfig.get("timeout",
                                      10000),
          allow_redirects=self.httpConfig.get("allow_redirects",
                                              False)
      )
      res.encoding = self.httpConfig.get("res_encoding", 'utf-8')
    except Exception as ex:
      if LogUtil:
        LogUtil.error(ex, f"请求发送失败 - [url: {url}]")
      else:
        traceback.extract_stack()
    return res

  # 发起 get 请求
  def get(
      self,
      path: str,
      headers: Dict[str,
                    str] = None
  ) -> requests.Response:
    return self.req(method="get", path=path, headers=headers)

  # 发起 post 请求
  def post(
      self,
      path: str,
      data: Any = None,
      headers: Dict[str,
                    str] = None
  ) -> requests.Response:
    return self.req(method="post", path=path, headers=headers, data=data)

  # 拼接链接
  def combineUrl(self, path: str) -> str:
    """拼接链接

    Args:
        path (str): 链接路径

    Returns:
        url (str): 链接全路径
    """

    url = self.httpConfig.get('host') + path
    return url